package 线程;

import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.ReentrantLock;

/**
 * @author:谢君臣
 * @Date:2021/9/13-16:46
 * @version:1.0
 * @function:
 */
public class 交替打印 {

    public static void main(String[] args) {
        Resource resource = new Resource();
        new Thread(()->{
            for (int i = 0; i < 10; i++) {
                resource.PrintA(()-> System.out.println("A"));
            }
        }).start();
        new Thread(()->{
            for (int i = 0; i < 10; i++) {
                resource.PrintB(()-> System.out.println("B"));
            }
        }).start();
        new Thread(()->{
            for (int i = 0; i < 10; i++) {
                resource.PrintC(()-> System.out.println("C"));
            }
        }).start();

    }
    static class Resource{
        private AtomicInteger state = new AtomicInteger(0);
        ReentrantLock lock = new ReentrantLock();
        Condition condition1 = lock.newCondition();
        Condition condition2 = lock.newCondition();
        Condition condition3 = lock.newCondition();

        public Resource() {
        }

        public void PrintA(Runnable print){
            lock.lock();
            try {
                if (state.get()%3!=0)
                    condition1.await();
                print.run();
                state.incrementAndGet();
                condition2.signal();
            }catch (Exception e){
                e.printStackTrace();
            }finally {
                lock.unlock();
            }
        }
        public void PrintB(Runnable print){
            lock.lock();
            try {
                if (state.get()%3!=1)
                    condition2.await();
                print.run();
                state.incrementAndGet();
                condition3.signal();
            }catch (Exception e){
                e.printStackTrace();
            }finally {
                lock.unlock();
            }
        }
        public void PrintC(Runnable print){
            lock.lock();
            try {
                if (state.get()%3!=2)
                    condition3.await();
                print.run();
                state.incrementAndGet();
                condition1.signal();
            }catch (Exception e){
                e.printStackTrace();
            }finally {
                lock.unlock();
            }
        }
    }
}
